<template>
  <div class="authenticated-image" :style="containerStyle">
    <el-image
      v-if="imageSrc"
      :src="imageSrc"
      :preview-src-list="previewList"
      :fit="fit"
      :style="imageStyle"
      :preview-teleported="true"
      @error="handleImageError"
    >
      <template #error>
        <div class="image-error">
          <el-icon><Picture /></el-icon>
          <span>无法加载</span>
        </div>
      </template>
    </el-image>
    <div v-else-if="loading" class="image-loading" :style="imageStyle">
      <el-icon class="is-loading"><Loading /></el-icon>
      <span>加载中...</span>
    </div>
    <div v-else class="image-error" :style="imageStyle">
      <el-icon><Picture /></el-icon>
      <span>加载失败</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';
import { Picture, Loading } from '@element-plus/icons-vue';
import http from '@/api';
import { useUserStore } from '@/stores/modules/user';

interface Props {
  src: string;
  fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
  style?: Record<string, any>;
}

const props = withDefaults(defineProps<Props>(), {
  fit: 'cover',
  style: () => ({})
});

const userStore = useUserStore();
const imageSrc = ref<string>('');
const loading = ref(false);
const error = ref(false);

// 图片blob缓存
const imageBlobCache = new Map<string, string>();

const containerStyle = computed(() => props.style);
const imageStyle = computed(() => ({
  ...props.style,
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  backgroundColor: '#f5f7fa',
  color: '#909399',
  fontSize: '12px'
}));

const previewList = computed(() => {
  return imageSrc.value ? [imageSrc.value] : [];
});

// 使用axios获取带认证的图片并转换为blob URL
const loadAuthenticatedImage = async (url: string): Promise<string> => {
  if (!url || !userStore.token) return url;
  
  // 检查缓存
  if (imageBlobCache.has(url)) {
    return imageBlobCache.get(url)!;
  }
  
  try {
    console.log('Loading authenticated image:', url);
    
    // 使用axios获取图片，这样会自动添加认证头
    const response = await http.get(url, {}, { responseType: 'blob' });
    
    // 创建blob URL
    const blobUrl = URL.createObjectURL(response.data as Blob);
    
    // 缓存blob URL
    imageBlobCache.set(url, blobUrl);
    
    console.log('Image loaded successfully:', blobUrl);
    return blobUrl;
  } catch (error) {
    console.error('Failed to load authenticated image:', error);
    throw error;
  }
};

// 加载图片
const loadImage = async () => {
  if (!props.src) return;
  
  loading.value = true;
  error.value = false;
  
  try {
    const blobUrl = await loadAuthenticatedImage(props.src);
    imageSrc.value = blobUrl;
  } catch (err) {
    console.error('Failed to load image:', err);
    error.value = true;
    imageSrc.value = '';
  } finally {
    loading.value = false;
  }
};

// 处理图片加载错误
const handleImageError = () => {
  console.error('Image display error for:', props.src);
  error.value = true;
};

// 清理blob缓存
const cleanupImageCache = () => {
  imageBlobCache.forEach(blobUrl => {
    URL.revokeObjectURL(blobUrl);
  });
  imageBlobCache.clear();
};

// 监听src变化
watch(() => props.src, loadImage, { immediate: true });

onMounted(() => {
  loadImage();
});

onBeforeUnmount(() => {
  // 清理当前组件使用的blob URL
  if (imageSrc.value && imageSrc.value.startsWith('blob:')) {
    URL.revokeObjectURL(imageSrc.value);
  }
});
</script>

<style scoped lang="scss">
.authenticated-image {
  .image-error,
  .image-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    
    .el-icon {
      font-size: 16px;
    }
    
    span {
      font-size: 10px;
    }
  }
  
  .image-loading {
    .el-icon.is-loading {
      animation: rotating 2s linear infinite;
    }
  }
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>